﻿using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.DirectoryServices;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Reflection;
using System.Security;
using System.Text;

namespace Helper
{
	/// <summary>
	/// ADEL: Active Directory - Exchange - Lync
	/// </summary>
	public static class ADEL
	{
		#region [Properties & Constants] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		private class Message
		{
			public const string NoUserInDC = "User name could not be found in Active Directory! Searched User Name: {0}";
			public const string NoGroupNameInDC = "Group name could not be found in Active Directory! Searched Group Name: {0}";
		}

		private const string DefaultDomain = "default.gov.tr";

		private static string ActiveDirectorySetPath
		{
			get
			{
				string s = ActiveDirectorySearchPath;
				s = string.Format("{0}/{1}/{2}/{3},{4}", s.Split('/').GetValue(0)
														, s.Split('/').GetValue(1)
														, s.Split('/').GetValue(2)
														, "LDAPOU".ReadAppSetting<string>()
														, s.Split('/').GetValue(3));
				return s;
			}
		}
		private static string ActiveDirectorySearchPath
		{
			get { return "LDAPPath".ReadAppSetting<string>(); }
		}
		private static string ActiveDirectoryControlUserName
		{
			get { return "ActiveDirectoryControlUser".ReadAppSetting<string>(); }
		}
		private static string ActiveDirectoryControlUserPassword
		{
			get { return "ActiveDirectoryControlUserPassword".ReadAppSetting<string>().Decrypt(); }
		}
		private static string ActiveDirectorySchemaEntryName
		{
			get { return "ActiveDirectorySchemaEntryName".ReadAppSetting<string>(); }
		}

		private static DirectoryEntry ActiveDirectoryEntryToSet
		{
			get { return new DirectoryEntry(ActiveDirectorySetPath, ActiveDirectoryControlUserName, ActiveDirectoryControlUserPassword); }
		}

		private static DirectoryEntry ActiveDirectoryEntryToSearch
		{
			get { return new DirectoryEntry(ActiveDirectorySearchPath, ActiveDirectoryControlUserName, ActiveDirectoryControlUserPassword); }
		}

		private static int ActiveDirectoryPasswordExpirePeriod
		{
			get { return Convert.ToInt32("ActiveDirectoryPasswordExpirePeriod".ReadAppSetting<int>(90)); }
		}

		private static string LiveIdConnectionUri
		{
			get { return "LiveIdConnectionUri".ReadAppSetting<string>(); }
		}
		private static string ShellUri
		{
			get { return "MicrosoftExchangeSchema".ReadAppSetting<string>(); }
		}
		private static string LyncConnectionUri
		{
			get { return "LyncConnectionUri".ReadAppSetting<string>(); }
		}
		private static string LyncRegistryPool
		{
			get { return "LyncRegistryPool".ReadAppSetting<string>(); }
		}

		private struct UserAccountControlFlags
		{
			public const int SCRIPT = 0x0001;
			public const int ACCOUNTDISABLE = 0x0002;
			public const int HOMEDIR_REQUIRED = 0x0008;
			public const int LOCKOUT = 0x0010;
			public const int ASSWD_NOTREQD = 0x0020;
			public const int PASSWD_CANT_CHANGE = 0x0040;
			public const int ENCRYPTED_TEXT_PWD_ALLOWED = 0x0080;
			public const int TEMP_DUPLICATE_ACCOUNT = 0x0100;
			public const int NORMAL_ACCOUNT = 0x0200;
			public const int INTERDOMAIN_TRUST_ACCOUNT = 0x0800;
			public const int WORKSTATION_TRUST_ACCOUNT = 0x1000;
			public const int SERVER_TRUST_ACCOUNT = 0x2000;
			public const int DONT_EXPIRE_PASSWORD = 0x10000;
			public const int MNS_LOGON_ACCOUNT = 0x20000;
			public const int SMARTCARD_REQUIRED = 0x40000;
			public const int TRUSTED_FOR_DELEGATION = 0x80000;
			public const int NOT_DELEGATED = 0x100000;
			public const int USE_DES_KEY_ONLY = 0x200000;
			public const int DONT_REQ_PREAUTH = 0x400000;
			public const int PASSWORD_EXPIRED = 0x800000;
			public const int TRUSTED_TO_AUTH_FOR_DELEGATION = 0x1000000;
		}

		public struct UserInformation
		{
			private string kullaniciAdi;
			private string sifre;
			private string tcKimlikNo;
			private string ad;
			private string soyad;
			private string telefon;
			private string basvuruyuYapan;
			private string sehir;
			private string kadroYeri;
			private string calistigiYer;
			private string unvan;
			private string sinif;
			private bool ePostaHesabiOlustur;
			private bool lyncHesabiOlustur;

			public string KullaniciAdi { get { return kullaniciAdi; } set { kullaniciAdi = value; } }
			public string Sifre { get { return sifre; } set { sifre = value; } }
			public string TcKimlikNo { get { return tcKimlikNo; } set { tcKimlikNo = value; } }
			public string Ad { get { return ad; } set { ad = value; } }
			public string Soyad { get { return soyad; } set { soyad = value; } }
			public string Telefon { get { return telefon; } set { telefon = value; } }
			public string Basvuran { get { return basvuruyuYapan; } set { basvuruyuYapan = value; } }
			public string Sehir { get { return sehir; } set { sehir = value; } }
			public string KadroYeri { get { return kadroYeri; } set { kadroYeri = value; } }
			public string CalistigiYer { get { return calistigiYer; } set { calistigiYer = value; } }
			public string Unvan { get { return unvan; } set { unvan = value; } }
			public string Sinif { get { return sinif; } set { sinif = value; } }
			public bool EPostaHesabiOlustur { get { return ePostaHesabiOlustur; } set { ePostaHesabiOlustur = value; } }
			public bool LyncHesabiOlustur { get { return lyncHesabiOlustur; } set { lyncHesabiOlustur = value; } }
		}

		public enum ProcessInfo
		{
			NoInfo = 0,
			UserAlreadyExistOnActiveDirectory = 1,
			UserAlreadyExistOnMailBox = 2,
			UserAlreadyExistOnLync = 3
		}

		#endregion

		#region [Common Methods] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		public static void CheckError(PowerShell pPowerShell)
		{
			StringBuilder errorList = new StringBuilder();
			if (pPowerShell.Streams.Error.Count > 0)
			{
				foreach (object item in pPowerShell.Streams.Error.ReadAll())
				{
					errorList.Append(item.ToString());
					errorList.Append(System.Environment.NewLine);
				}
				throw new ApplicationException(errorList.ToString());
			}
		}

		private static DirectoryEntry GetUser(string pUserName)
		{
			SearchResult objResult = SearchUser(pUserName);

			if (objResult != null)
			{
				DirectoryEntry entryToUpdate = objResult.GetDirectoryEntry();
				return entryToUpdate;
			}
			else
			{
				throw new ApplicationException(string.Format(Message.NoUserInDC, pUserName));
			}
		}

		private static SearchResult SearchUser(string pUserName)
		{
			DirectoryEntry objRootEntry = ActiveDirectoryEntryToSearch;
			DirectorySearcher objADSearcher = new DirectorySearcher(objRootEntry);

			objADSearcher.Filter = string.Format("(userPrincipalName={0})", pUserName);
			objADSearcher.PropertiesToLoad.Add("cn");
			return objADSearcher.FindOne();
		}

		private static DirectoryEntry GetGroup(string pGroupName)
		{
			DirectoryEntry objRootEntry = ActiveDirectoryEntryToSearch;
			DirectorySearcher objADSearcher = new DirectorySearcher(objRootEntry);

			objADSearcher.Filter = string.Format("(&(objectClass=group)(cn={0}))", pGroupName);
			SearchResult objResult = objADSearcher.FindOne();
			if (objResult != null)
			{
				DirectoryEntry entryToUpdate = objResult.GetDirectoryEntry();
				return entryToUpdate;
			}
			else
			{
				throw new ApplicationException(string.Format(Message.NoGroupNameInDC, pGroupName));
			}
		}

		private static SecureString GetActiveDirectoryControlPasswordAsSecureString()
		{
			SecureString password = new SecureString();
			foreach (char x in ActiveDirectoryControlUserPassword)
			{
				password.AppendChar(x);
			}
			return password;
		}

		private static void GetPSObjects(Uri uri, string shellUri, out Runspace runspace, out PowerShell powershell, out PSCommand command)
		{
			SecureString password = GetActiveDirectoryControlPasswordAsSecureString();
			PSCredential credential = new PSCredential(ActiveDirectoryControlUserName, password);
			WSManConnectionInfo connectionInfo = new WSManConnectionInfo(uri, shellUri, credential);
			connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Default;
			runspace = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace(connectionInfo);
			powershell = PowerShell.Create();
			command = new PSCommand();
		}

		private static string GetUserPrincipleName(string pUserCommonName)
		{
			return string.Format("{0}@{1}", pUserCommonName, "LDAP_DC".ReadAppSetting<string>(DefaultDomain));
		}

		#endregion

		#region [Active Directory] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		public static void CreateNewUserOnActiveDirectory(UserInformation pUserInfo, ref ProcessInfo pProcessInfo)
		{
			if (IsUserExistOnActiveDirectory(GetUserPrincipleName(pUserInfo.KullaniciAdi)))
			{
				pProcessInfo = ProcessInfo.UserAlreadyExistOnActiveDirectory;
				return;
			}

			DirectoryEntry adUserFolder = ActiveDirectoryEntryToSet;

			if (adUserFolder.SchemaEntry.Name == ActiveDirectorySchemaEntryName)
			{
				DirectoryEntry newUser = adUserFolder.Children.Add(string.Format("CN={0}", pUserInfo.KullaniciAdi), "user");

				//Save User Informations
				newUser.Properties["sAMAccountName"].Value = pUserInfo.KullaniciAdi.SubstringExt(0, 20);
				newUser.Properties["userPrincipalName"].Value = GetUserPrincipleName(pUserInfo.KullaniciAdi);
				newUser.Properties["givenName"].Value = pUserInfo.Ad;
				newUser.Properties["SN"].Value = pUserInfo.Soyad;
				newUser.Properties["description"].Value = pUserInfo.TcKimlikNo;
				newUser.Properties["displayName"].Value = string.Format("{0} {1}", pUserInfo.Ad, pUserInfo.Soyad);

				newUser.Properties["initials"].Value = string.Format("{0}{1}", pUserInfo.Ad.Substring(0, 1).ToUpper(), pUserInfo.Soyad.Substring(0, 1).ToUpper());
				newUser.Properties["telephoneNumber"].Value = pUserInfo.Telefon;
				newUser.Properties["info"].Value = pUserInfo.Basvuran;
				newUser.Properties["l"].Value = pUserInfo.Sehir;
				newUser.Properties["company"].Value = pUserInfo.KadroYeri;
				newUser.Properties["department"].Value = pUserInfo.CalistigiYer;
				newUser.Properties["title"].Value = pUserInfo.Unvan;

				try
				{
					newUser.CommitChanges();
				}
				catch (Exception)
				{
					newUser.Close();
					throw;
				}

				//Set Password
				newUser.Invoke("setpassword", pUserInfo.Sifre);
				newUser.Properties["userAccountControl"].Value = UserAccountControlFlags.NORMAL_ACCOUNT;
				newUser.Properties["userAccountControl"].Value = UserAccountControlFlags.DONT_EXPIRE_PASSWORD;

				try
				{
					newUser.CommitChanges();
				}
				catch (Exception)
				{
					//If error occured while password was creating, delete user 
					IfExistDeleteUserOnActiveDirectory(newUser, adUserFolder);
					throw;
				}
				finally
				{
					newUser.Close();
				}

				if (pUserInfo.EPostaHesabiOlustur) CreateNewUserOnMailBox(pUserInfo.KullaniciAdi, pUserInfo.KullaniciAdi, ref pProcessInfo);
				if (pUserInfo.LyncHesabiOlustur) CreateNewUserOnLync(pUserInfo.KullaniciAdi, ref pProcessInfo);
			}
		}

		public static void SetNewPassword(string pUserName, string pPassword)
		{
			DirectoryEntry user = GetUser(pUserName);
			try
			{
				object ret = user.Invoke("SetPassword", pPassword);
				user.CommitChanges();
			}
			catch (TargetInvocationException exc)
			{
				if (exc.InnerException.ToString().Contains("0x80072035"))	//The server is unwilling to process the request. (Exception from HRESULT: 0x80072035)
				{
					throw new ApplicationException(@"<b>Error Occured On Active Directory !</b><br /><br /> 
													Probably, your new password is not suitable for password security policy.<br />
													Please check your password and try again.
													If the problem persists, contact with your system administration or call center.<br /><br />
													Your password should include at least <b>1 letter</b>, at least <b>1 number</b> and at least <b>1 symbol</b>.
													Password length should be minimum 8 chacter, it should not include your name or sername and should not be consecutive letter or number.
													");
				}
				throw;
			}
			finally
			{
				user.Close();
			}
		}

		public static bool IsPasswordExpired(string pUserName)
		{
			DirectoryEntry user = GetUser(pUserName);
			Int64 pls;
			string attrName = "pwdLastSet";

			if (user != null && user.Properties[attrName] != null && user.Properties[attrName].Value != null)
			{
				pls = ConvertADSLargeIntegerToInt64(user.Properties[attrName].Value);
				double increment = (pls - (Int64)47966688000000000) / ((double)600000000);
				DateTime dtPls = new DateTime(1753, 1, 1).AddMinutes(increment);
				DateTime dtPwExpire = dtPls.AddDays(ActiveDirectoryPasswordExpirePeriod);
				return dtPwExpire < DateTime.Now.Date;
			}

			return false;
		}

		public static bool IsUserExistOnActiveDirectory(string pUserName)
		{
			SearchResult objResult = SearchUser(pUserName);
			return objResult != null ? true : false;
		}

		public static bool IsUserAuthorizedOnActiveDirectory(string pUserName, string pPasword)
		{
			DirectoryEntry entry = new DirectoryEntry(ActiveDirectorySearchPath, pUserName, pPasword);

			try
			{
				if (entry.Name == null)
				{
					return false;
				}
				else
				{
					return true;
				}
			}
			catch (Exception exc)
			{
				if (!exc.Message.Contains("Logon failure"))
				{
					string errMsg = string.Format("Login Error Occured: {0}", exc.ToString());
					EventLog.WriteEntry(Constants.EventLogSource.Application, exc.ToString(), EventLogEntryType.Error, 0);
				}
				return false;
			}
			finally
			{
				entry.Close();
			}
		}

		public static void AddUserToGroup(string pUserName, string pGroupName)
		{
			using (DirectoryEntry dirEntry = GetGroup(pGroupName))
			{
				dirEntry.Properties["member"].Add(GetUser(pUserName));
				dirEntry.CommitChanges();
			}

		}

		public static void RemoveUserFromGroup(string pUserName, string pGroupName)
		{
			using (DirectoryEntry dirEntry = GetGroup(pGroupName))
			{
				dirEntry.Properties["member"].Remove(GetUser(pUserName));
				dirEntry.CommitChanges();
			}
		}

		public static void DeleteGroup(string pGroupName)
		{
			using (DirectoryEntry entry = ActiveDirectoryEntryToSet)
			{
				using (DirectoryEntry group = GetGroup(pGroupName))
				{
					entry.Children.Remove(group);
					group.CommitChanges();
				}
			}
		}

		private static string GetLdapGroupPath(string pGroupName)
		{
			string s = ActiveDirectorySearchPath;
			string ldapGroupPath = string.Format("{0}/{1}/{2}/{3},{4}", s.Split('/').GetValue(0)
																						 , s.Split('/').GetValue(1)
																						 , s.Split('/').GetValue(2)
																						 , string.Format("cn={0}", pGroupName)
																						 , s.Split('/').GetValue(3));
			return ldapGroupPath;
		}

		public static void CreateNewGroup(string pGroupName)
		{
			string ldapGroupPath = GetLdapGroupPath(pGroupName);

			if (!DirectoryEntry.Exists(ldapGroupPath))
			{
				using (DirectoryEntry entry = ActiveDirectoryEntryToSet)
				{
					using (DirectoryEntry group = entry.Children.Add(ldapGroupPath, "group"))
					{
						group.Properties["sAmAccountName"].Value = pGroupName;
						group.CommitChanges();
					}
				}
			}
			else
			{
				throw new ApplicationException("Grup adı sistemde zaten var!");
			}
		}

		public static void EnableUserAccount(string pUserName)
		{
			DirectoryEntry user = GetUser(pUserName);
			int val = (int)user.Properties["userAccountControl"].Value;
			user.Properties["userAccountControl"].Value = val & ~UserAccountControlFlags.ACCOUNTDISABLE;

			user.CommitChanges();
			user.Close();
		}

		public static void DisableUserAccount(string pUserName)
		{
			DirectoryEntry user = GetUser(pUserName);
			int val = (int)user.Properties["userAccountControl"].Value;
			user.Properties["userAccountControl"].Value = val | UserAccountControlFlags.ACCOUNTDISABLE;

			user.CommitChanges();
			user.Close();
		}

		#region [Privet Methods] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		private static string GetExchangeServerDbName(string pUserAcountName)
		{
			string firstLetter = pUserAcountName.Substring(0, 1);

			switch (firstLetter)
			{
				case "a": return "MailBoxes_A";
				case "b": return "MailBoxes_B";
				case "c": return "MailBoxes_CD";
				case "d": return "MailBoxes_CD";
				case "e": return "MailBoxes_E";
				case "f": return "MailBoxes_F";
				case "g": return "MailBoxes_G";
				case "h": return "MailBoxes_H";
				case "i": return "MailBoxes_I";
				case "j": return "MailBoxes_JKL";
				case "k": return "MailBoxes_JKL";
				case "l": return "MailBoxes_JKL";
				case "m": return "MailBoxes_M";
				case "n": return "MailBoxes_N";
				case "o": return "MailBoxes_O";
				case "p": return "MailBoxes_PR";
				case "r": return "MailBoxes_PR";
				case "s": return "MailBoxes_S";
				case "t": return "MailBoxes_TUVX";
				case "u": return "MailBoxes_TUVX";
				case "v": return "MailBoxes_TUVX";
				case "y": return "MailBoxes_YZ";
				case "z": return "MailBoxes_YZ";
				case "q": return "MailBoxes_O";
				case "w": return "MailBoxes_TUVX";
				case "x": return "MailBoxes_TUVX";
				default:
					return "MailBoxes_A";
			}
		}

		public static void IfExistDeleteUserOnActiveDirectory(DirectoryEntry pNewUser, DirectoryEntry pAdUserFolder)
		{
			if (DirectoryEntry.Exists(pNewUser.Path))
			{
				pAdUserFolder.Children.Remove(new DirectoryEntry(pNewUser.Path));
			}
		}

		private static Int64 ConvertADSLargeIntegerToInt64(object pAdsLargeInteger)
		{
			var highPart = (Int32)pAdsLargeInteger.GetType().InvokeMember("HighPart", System.Reflection.BindingFlags.GetProperty, null, pAdsLargeInteger, null);
			var lowPart = (Int32)pAdsLargeInteger.GetType().InvokeMember("LowPart", System.Reflection.BindingFlags.GetProperty, null, pAdsLargeInteger, null);
			return highPart * ((Int64)UInt32.MaxValue + 1) + lowPart;
		}

		#endregion

		#endregion

		#region [Exchange Server] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		public static void CreateNewUserOnMailBox(string pUserCommonName, string pUserLogonName, ref ProcessInfo pProcessInfo)
		{
			Runspace runspace;
			PowerShell powershell;
			PSCommand command;
			Uri uri = (new Uri(LiveIdConnectionUri, UriKind.Absolute));
			GetPSObjects(uri, ShellUri, out runspace, out powershell, out command);

			if (IsMailBoxAlreadyExist(pUserCommonName, runspace, powershell, command))
			{
				pProcessInfo = ProcessInfo.UserAlreadyExistOnMailBox;
				return;
			}

			command.AddCommand("Enable-Mailbox");
			command.AddParameter("Identity", pUserCommonName);
			command.AddParameter("Alias", pUserLogonName);
			command.AddParameter("Database", GetExchangeServerDbName(pUserLogonName));

			powershell.Commands = command;

			try
			{
				runspace.Open();
				powershell.Runspace = runspace;
				powershell.Invoke();
				CheckError(powershell);
			}
			finally
			{
				runspace.Dispose();
				runspace = null;
				powershell.Dispose();
				powershell = null;
			}
		}

		public static bool IsMailBoxAlreadyExist(string pUserCommonName, Runspace pRunspace, PowerShell pPowerShell, PSCommand pPSCommand)
		{
			if (!IsUserExistOnActiveDirectory(GetUserPrincipleName(pUserCommonName))) return false;

			pPSCommand.AddCommand("Get-Mailbox");
			pPSCommand.AddParameter("Identity", pUserCommonName);

			pPowerShell.Commands = pPSCommand;

			try
			{
				pRunspace.Open();
				pPowerShell.Runspace = pRunspace;
				Collection<PSObject> user = pPowerShell.Invoke();

				if (user == null || user.Count == 0) return false;

				CheckError(pPowerShell);

				PSMemberInfo item = user[0].Properties.Where(property => property.Name == "RecipientType").SingleOrDefault();

				if (item != null)
				{
					if (string.Equals(item.Value.ToString(), "UserMailbox", StringComparison.OrdinalIgnoreCase))
					{
						return true;
					}
				}
				return false;
			}
			finally
			{
				pRunspace.Dispose();
				pRunspace = null;
			}
		}

		/// <summary>
		/// Used to check if MS Exchange Server version is 2010 or not
		/// </summary>
		/// <param name="pKullaniciAdi"></param>
		/// <returns></returns>
		public static bool IsExchangeServerVersion2010(string pKullaniciAdi)
		{
			bool rc = false;

			SearchResult objResult = SearchUser(pKullaniciAdi);
			if (objResult != null)
			{
				string mtaValue = objResult.Properties["homemta"][0].ToString();
				if (mtaValue.Contains("CN=IB07EDB"))
				{
					rc = true;
				}
			}
			return rc;
		}

		#endregion

		#region [Lync Server] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

		public static void CreateNewUserOnLync(string pUserCommonName, ref ProcessInfo pProcessInfo)
		{
			Runspace runspace;
			PowerShell powershell;
			PSCommand command;
			Uri uri = (new Uri(LyncConnectionUri, UriKind.Absolute));
			GetPSObjects(uri, string.Empty, out runspace, out powershell, out command);

			if (IsLyncAccountAlreadyExist(pUserCommonName, runspace, powershell, command))
			{
				pProcessInfo = ProcessInfo.UserAlreadyExistOnLync;
				return;
			}

			command.AddCommand("Enable-CsUser");
			command.AddParameter("Identity", pUserCommonName);
			command.AddParameter("RegistrarPool", LyncRegistryPool);
			command.AddParameter("SipAddressType", "UserPrincipalName");

			powershell.Commands = command;

			try
			{
				runspace.Open();
				powershell.Runspace = runspace;
				powershell.Invoke();
				CheckError(powershell);
			}
			finally
			{
				runspace.Dispose();
				runspace = null;
				powershell.Dispose();
				powershell = null;
			}
		}

		private static bool IsLyncAccountAlreadyExist(string pUserCommonName, Runspace pRunspace, PowerShell pPowerShell, PSCommand pPSCommand)
		{
			if (!IsUserExistOnActiveDirectory(GetUserPrincipleName(pUserCommonName))) return false;

			pPSCommand.AddCommand("Get-CsUser");
			pPSCommand.AddParameter("Identity", pUserCommonName);

			pPowerShell.Commands = pPSCommand;

			try
			{
				pRunspace.Open();
				pPowerShell.Runspace = pRunspace;
				Collection<PSObject> user = pPowerShell.Invoke();

				if (user == null || user.Count == 0) return false; else return true;
			}
			finally
			{
				pRunspace.Dispose();
				pRunspace = null;
			}
		}

		#endregion
	}
}
